//
//  AHSetting.swift
//  AttributedStringHelper
//
//  Created by JY_NEW on 2021/11/1.
//

import Foundation

public enum AHSetting {
    case attribute(NSAttributedString.Key, Any)
    case attributes([NSAttributedString.Key: Any])
    public func attributes() -> [NSAttributedString.Key: Any] {
        switch self {
        case let .attribute(key, value): return [key: value]
        case let .attributes(dict): return dict
        }
    }
}
extension Array where Element == AHSetting {
    public func attributes() -> [NSAttributedString.Key: Any] {
        return self.reduce(into: [:]) { partialResult, setting in
            switch setting {
            case let .attribute(key, value): partialResult[key] = value
            case let .attributes(dict): partialResult.merge(dict, uniquingKeysWith: { $1 })
            }
        }
    }
}
extension NSMutableAttributedString {
    /// 设置全局样式
    public func set(_ settings: AHSetting...) {
        self.addAttributes(settings.attributes(), range: NSMakeRange(0, self.length))
    }
    /// 设置指定字符串样式
    public func set(_ settings: AHSetting..., for string: String, options: NSString.CompareOptions = []) {
        let fulLString = self.string as NSString
        let count = self.string.count
        var range = fulLString.range(of: string, options: options)
        while range.location != NSNotFound {
            self.addAttributes(settings.attributes(), range: NSMakeRange(range.location, range.length))
            let start = range.location + range.length
            range = fulLString.range(of: string, options: options, range: NSMakeRange(start, count - start))
        }
    }
    /// 设置指定区域样式
    public func set(_ settings: AHSetting..., at loc: Int, count: Int) {
        self.addAttributes(settings.attributes(), range: NSMakeRange(loc, count))
    }
    /// 设置指定正则匹配的字符串样式
    public func set(_ settings: AHSetting..., regex: String, options: NSRegularExpression.Options = []) {
        if let reg = try? NSRegularExpression(pattern: regex, options: options) {
            let attrs = settings.attributes()
            reg.enumerateMatches(in: self.string, options: .reportProgress, range: NSRange(location: 0, length: self.string.count)) { (result, flags, _) in
                if let r = result {
                    self.addAttributes(attrs, range: r.range)
                }
            }
        }
    }
    /// 插入字符串到指定位置
    public func insert(_ settings: AHSetting..., for string: String, at loc: Int) {
        let text = NSAttributedString(string: string, attributes: settings.attributes())
        self.insert(text, at: loc)
    }
    /// 插入图片到指定位置
    public func insert(_ image: UIImage?, bounds: CGRect? = nil, at loc: Int) {
        if let image = image {
            let attachment = NSTextAttachment()
            attachment.image = image
            attachment.bounds = bounds ?? CGRect(origin: .zero, size: image.size)
            let text = NSAttributedString(attachment: attachment)
            self.insert(text, at: loc)
        }
    }
    /// 插入数据到指定位置
    public func insert(_ data: Data?, type: String?, at loc: Int) {
        let attachment = NSTextAttachment(data: data, ofType: type)
        let text = NSAttributedString(attachment: attachment)
        self.insert(text, at: loc)
    }
    /// 插入文件到指定位置
    public func insert(_ file: FileWrapper, at loc: Int) {
        let attachment = NSTextAttachment()
        attachment.fileWrapper = file
        let text = NSAttributedString(attachment: attachment)
        self.insert(text, at: loc)
    }
    /// 插入字符串到指定位置
//    public func insert(_ string: String, at loc: Int) {
//        self.insert(.init(string: string), at: loc)
//    }
    /// 添加字符串到指定位置
    public func append(_ settings: AHSetting..., for string: String) {
        let text = NSAttributedString(string: string, attributes: settings.attributes())
        self.append(text)
    }
    /// 添加图片到指定位置
    public func append(_ image: UIImage?, bounds: CGRect? = nil) {
        if let image = image {
            let attachment = NSTextAttachment()
            attachment.image = image
            attachment.bounds = bounds ?? CGRect(origin: .zero, size: image.size)
            let text = NSAttributedString(attachment: attachment)
            self.append(text)
        }
    }
    /// 添加数据到指定位置
    public func append(_ data: Data?, type: String?) {
        let attachment = NSTextAttachment(data: data, ofType: type)
        let text = NSAttributedString(attachment: attachment)
        self.append(text)
    }
    /// 添加文件到指定位置
    public func append(_ file: FileWrapper) {
        let attachment = NSTextAttachment()
        attachment.fileWrapper = file
        let text = NSAttributedString(attachment: attachment)
        self.append(text)
    }
}
extension String {
    /// 转为富文本
    public func asAttributed(_ settings: AHSetting...) -> NSAttributedString {
        return .init(string: self, attributes: settings.attributes())
    }
}
